package sunwul.datasource.service.impl;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import sunwul.datasource.entity.TAdmin_springTran;
import sunwul.datasource.service.TAdminService_springTran;

import java.util.List;

/**
 * @author sunwul
 * @date 2022/3/10 22:25:46
 * @description
 */
@Service
public class TAdminServiceImpl_springTran implements TAdminService_springTran {

    @Autowired
    sunwul.datasource.mapper.read.TAdminMapper_springTran TAdminMapper_R;

    @Autowired
    sunwul.datasource.mapper.write.TAdminMapper_springTran TAdminMapper_W;

    @Autowired
    TransactionTemplate transactionTemplate_w;

    @Autowired
    TransactionTemplate transactionTemplate_r;

    @Override
    public List<TAdmin_springTran> sel_admin() {
        return TAdminMapper_R.sel_admin();
    }

    /**
     * 添加数据, 制造异常,触发事务
     * 由于此时写库的事务管理添加了@Primary注解, 因此此时只有写库的事务会生效
     * 此时会因为数据库操作的顺序出现以下几种情况:
     * 1. 当写库操作或读库操作位于异常代码之前时:  读库正常插入数据, 写库回滚操作
     * 2. 当读库操作位于异常代码之前,写库操作位于异常代码之后时:  读库正常插入数据, 不会执行到写库操作, 直接抛出异常
     * 3. 当写库操作位于异常代码之前,读库操作位于异常代码之后时:  写库回滚操作, 不会执行到读库操作, 直接抛出异常
     * 综上:
     * 开启了对应数据库的事务管理后, 当出现异常情况时, 会回滚操作
     */
    @Transactional
//    @Override
    public Integer add_admin_bak1(String name) {
        TAdminMapper_W.add_admin(name);
        TAdminMapper_R.add_admin(name);
        int a = 1 / 0;
        return a;
    }

    /**
     * 通过Spring编程式事务对不同数据源进行事务控制
     */
    @Override
    public Integer add_admin(String name) {
        transactionTemplate_w.execute((status_w) -> {
            transactionTemplate_r.execute((status_r) -> {
                try {
                    TAdminMapper_W.add_admin(name);
                    TAdminMapper_R.add_admin(name);
                    int a = 1 / 0; // 制造异常,触发事务
                } catch (Exception e) {
                    e.printStackTrace();
                    status_w.setRollbackOnly(); // 调用写库的回滚
                    status_r.setRollbackOnly(); // 调用读库的回滚
                    return false;
                }
                return true;
            });
            return true;
        });
        return 999;
    }

}
